package com.hero.content.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hero.content.mapper.CoursePublishMapper;
import com.hero.content.model.dto.CourseBaseInfoDto;
import com.hero.content.model.dto.CoursePreviewDto;
import com.hero.content.model.dto.TeachplanDto;
import com.hero.content.model.pojo.*;
import com.hero.content.service.*;
import com.hero.execption.XueChengPlusException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author Mr.M
 * @version 1.0
 * @description TODO
 * @date 2022/9/16 15:37
 */
@Service
public class CoursePublishServiceImpl extends ServiceImpl<CoursePublishMapper, CoursePublish> implements CoursePublishService {

    @Autowired
    private CourseBaseService courseBaseInfoService;

    @Autowired
    private TeachplanService teachplanService;

    @Autowired
    private CourseMarketService marketService;

    @Autowired
    private CourseCategoryService categoryService;

    @Autowired
    private CoursePublishPreService preService;

    @Autowired
    private CourseAuditService auditService;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    /**
     * 根据课程id查询课程详情
     *
     * @param courseId 课程id
     * @return
     */
    @Override
    public CoursePreviewDto getCoursePreviewInfo(Long courseId) {
        //课程基本信息、营销信息
        CourseBaseInfoDto courseBaseInfo = courseBaseInfoService.getCourseBaseInfo(courseId);

        //课程计划信息
        List<TeachplanDto> teachplanTree = teachplanService.findTeachplanTree(courseId);

        CoursePreviewDto coursePreviewDto = new CoursePreviewDto();
        coursePreviewDto.setCourseBase(courseBaseInfo);
        coursePreviewDto.setTeachplans(teachplanTree);
        return coursePreviewDto;
    }

    /**
     * 课程提交审核业务代码
     *
     * @param courseId
     */
    @Override
    public void commitAudit(Long courseId) {
        // 校验
        if (ObjUtil.isEmpty(courseId)) XueChengPlusException.cast("课程ID不能为空");

        // 根据课程id获取课程的基本信息
        CourseBase courseBase = courseBaseInfoService.getById(courseId);

        if (ObjUtil.isEmpty(courseBase)) XueChengPlusException.cast("课程信息不存在");
        // 只能是未提交状态或者是已经审核出结果的状态 才可以提交审核
        // 等待审核的状态不能再次提交审核
        if (StrUtil.equals("202003", courseBase.getAuditStatus()))
            XueChengPlusException.cast("课程正在等待审核, 不能重复提交");

        // 本机构只能提交本机构的课程
        // courseBase.getCompanyId().equals("当前登录的机构ID")

        // 没有上传图片的不允许提交审核
        if (StrUtil.isEmpty(courseBase.getPic())) XueChengPlusException.cast("课程没有添加封面图片, 不允许提交审核");
        // 没有添加课程计划的不允许提交审核
        // 查询条件是 课程ID 查询的表是课程计划和课程计划媒资表
        List<TeachplanDto> teachplanTree = teachplanService.findTeachplanTree(courseId);
        if (CollUtil.isEmpty(teachplanTree))
            XueChengPlusException.cast("课程没有添加课程计划或者没有绑定视频, 不允许提交审核");

        CoursePublishPre publishPre = getPre(courseBase);

        // 新增/更新课程预发布表
        CoursePublishPre pre = preService.getById(publishPre.getId());
        if (ObjUtil.isNotNull(pre)) {
            // 更新
            preService.updateById(publishPre);
        } else {
            preService.save(publishPre);
        }

        // 修改课程基本信息表中的状态
        courseBase.setAuditStatus("202003");
        courseBaseInfoService.updateById(courseBase);
    }


    private CoursePublishPre getPre(CourseBase courseBase) {
        // 往预发布表中添加一条记录
        CoursePublishPre publishPre = new CoursePublishPre();
        BeanUtil.copyProperties(courseBase, publishPre);
        publishPre.setStName(categoryService.getById(courseBase.getSt()).getName());
        publishPre.setMtName(categoryService.getById(courseBase.getMt()).getName());

        // 查询课程营销信息
        CourseMarket market = marketService.getById(courseBase.getId());
        if (ObjUtil.isNotNull(market)) {
            publishPre.setMarket(JSONUtil.toJsonStr(market));
            BeanUtil.copyProperties(market, publishPre, "id");
        }

        // 查询课程计划信息
        List<TeachplanDto> teachplans = teachplanService.findTeachplanTree(courseBase.getId());
        if (CollUtil.isNotEmpty(teachplans)) publishPre.setTeachplan(JSONUtil.toJsonStr(teachplans));
        publishPre.setAuditStatus("202003");
        publishPre.setCreateDate(LocalDateTime.now());
        return publishPre;
    }

    /**
     * 运营人员提交审核结果的业务方法
     *
     * @param courseId    课程ID
     * @param successType 0 失败 1 成功
     */
    @Override
    public void auditCourse(Long courseId, Integer successType) {
        // 从预发布表中拿到审核信息
        CoursePublishPre publishPre = preService.getById(courseId);
        if (ObjUtil.isNull(publishPre)) XueChengPlusException.cast("课程未进行审核提交");
        // 把审核结果保存到审核记录表中
        // 根据审核结果去保存到审核记录表中
        CourseAudit audit = new CourseAudit();
        audit.setCourseId(courseId);
        if (0 == successType) {
            // 审核失败
            audit.setAuditMind("视频与课程内容无关");
            audit.setAuditStatus("202001");
        } else if (1 == successType) {
            // 审核成功
            audit.setAuditMind("审核通过");
            audit.setAuditStatus("202004");
        } else {
            XueChengPlusException.cast("审核参数非法");
        }

        // 正常情况下 应该是运营人员登录成功后 从Token中获取用户的ID
        audit.setAuditPeople("");
        audit.setAuditDate(LocalDateTime.now());
        auditService.save(audit);

        // 更新课程基本信息表
        CourseBase courseBase = courseBaseInfoService.getById(courseId);
        courseBase.setAuditStatus(successType == 0 ? "202001" : "202004");
        courseBaseInfoService.updateById(courseBase);

        // 删除预发布表中的数据记录
        // preService.removeById(courseId);
        publishPre.setAuditStatus(successType == 0 ? "202001" : "202004");
        preService.updateById(publishPre);
    }

    /**
     * 课程发布业务实现
     *
     * @param courseId
     */
    @Override
    public void publish(Long courseId) {
        if (ObjUtil.isNull(courseId)) XueChengPlusException.cast("参数非法");
        // 判断当前课程id的审核状态是否是通过
        CourseAudit audit = auditService.getOne(Wrappers.lambdaQuery(CourseAudit.class)
                .eq(CourseAudit::getCourseId, courseId)
                .eq(CourseAudit::getAuditStatus, "202004")
        );
        if (ObjUtil.isNull(audit)) XueChengPlusException.cast("课程尚未通过审核");
        // 操作发布表
        // 根据课程id 查询预发布表
        CoursePublishPre pre = preService.getById(courseId);
        CoursePublish coursePublish = new CoursePublish();
        BeanUtil.copyProperties(pre, coursePublish);
        this.save(coursePublish);

        // 发送消息给MQ
        // 消息内容怎么写 ??  依据是什么 ??
        // 依据是消费者怎么处理这个消息  消费者需要什么内容
        rabbitTemplate.convertAndSend("coursePublish", "", JSONUtil.toJsonStr(coursePublish));

        // 写MQ消费者  Redis缓存    暂时没有实现  基本信息
        // 写MQ消费者  ES数据添加   基本信息表数据
        // 写MQ消费者  Minio的上传  静态页面的生成  基本信息表 + 营销表 + 师资表
        // 多一次数据库的查询操作 直接传递一个课程ID

    }
}